/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.sample.android.wifi;

import java.util.Iterator;
import java.util.List;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pManager;
import android.net.wifi.p2p.WifiP2pManager.ActionListener;
import android.net.wifi.p2p.WifiP2pManager.Channel;
import android.net.wifi.p2p.WifiP2pManager.ChannelListener;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Toast;

import com.sample.android.dao.LienDataSource;
import com.sample.android.entity.Lien;
import com.sample.android.main.MainActivity;
import com.sample.android.sqlite.AfficherBase;
import com.sample.android.wifi.DeviceListFragment.DeviceActionListener;

/**
 * An activity that uses WiFi Direct APIs to discover and connect with available
 * devices. WiFi Direct APIs are asynchronous and rely on callback mechanism
 * using interfaces to notify the application of operation success or failure.
 * The application should also register a BroadcastReceiver for notification of
 * WiFi state related events.
 */
public class WiFiDirectActivity extends Activity implements ChannelListener,
		DeviceActionListener, OnClickListener
{
	public static final String	TAG					= "wifidirectLien";
	private WifiP2pManager		manager;
	private boolean				isWifiP2pEnabled	= false;
	private boolean				retryChannel		= false;

	private final IntentFilter	intentFilter		= new IntentFilter();
	private Channel				channel;
	private BroadcastReceiver	receiver			= null;

	/**
	 * @param isWifiP2pEnabled
	 *            the isWifiP2pEnabled to set
	 */
	public void setIsWifiP2pEnabled(boolean isWifiP2pEnabled)
	{
		this.isWifiP2pEnabled = isWifiP2pEnabled;
	}

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main_wifi);

		// add necessary intent values to be matched.
		intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
		intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
		intentFilter
				.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
		intentFilter
				.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);

		manager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
		channel = manager.initialize(this, getMainLooper(), null);

		findViewById(R.id.atn_direct_discover).setOnClickListener(this);
		findViewById(R.id.atn_direct_enable).setOnClickListener(this);
	}

	/** register the BroadcastReceiver with the intent values to be matched */
	@Override
	public void onResume()
	{
		super.onResume();
		receiver = new WiFiDirectBroadcastReceiver(manager, channel, this);
		registerReceiver(receiver, intentFilter);
	}

	@Override
	public void onPause()
	{
		super.onPause();
		unregisterReceiver(receiver);
	}

	/**
	 * Remove all peers and clear all fields. This is called on
	 * BroadcastReceiver receiving a state change event.
	 */
	public void resetData()
	{
		DeviceListFragment fragmentList = (DeviceListFragment) getFragmentManager()
				.findFragmentById(R.id.frag_list);
		DeviceDetailFragment fragmentDetails = (DeviceDetailFragment) getFragmentManager()
				.findFragmentById(R.id.frag_detail);
		if (fragmentList != null)
		{
			fragmentList.clearPeers();
		}
		if (fragmentDetails != null)
		{
			fragmentDetails.resetViews();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
	 */
	@Override
	public boolean onOptionsItemSelected(MenuItem item)
	{
		return super.onOptionsItemSelected(item);
	}

	@Override
	public void showDetails(WifiP2pDevice device)
	{
		DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager()
				.findFragmentById(R.id.frag_detail);
		fragment.showDetails(device);

	}

	@Override
	public void connect(WifiP2pConfig config)
	{
		manager.connect(channel, config, new ActionListener()
		{
			@Override
			public void onSuccess()
			{
				// WiFiDirectBroadcastReceiver will notify us. Ignore for now.
			}

			@Override
			public void onFailure(int reason)
			{
				Toast.makeText(WiFiDirectActivity.this,
						"Connect failed. Retry.", Toast.LENGTH_SHORT).show();
			}
		});
	}

	@Override
	public void disconnect()
	{
		final DeviceDetailFragment fragment = (DeviceDetailFragment) getFragmentManager()
				.findFragmentById(R.id.frag_detail);
		fragment.resetViews();
		manager.removeGroup(channel, new ActionListener()
		{
			@Override
			public void onFailure(int reasonCode)
			{
				Log.d(TAG, "Disconnect failed. Reason :" + reasonCode);
			}

			@Override
			public void onSuccess()
			{
				fragment.getView().setVisibility(View.GONE);
			}
		});
	}

	@Override
	public void onChannelDisconnected()
	{
		// we will try once more
		if (manager != null && !retryChannel)
		{
			Toast.makeText(this, "Channel lost. Trying again",
					Toast.LENGTH_LONG).show();
			resetData();
			retryChannel = true;
			manager.initialize(this, getMainLooper(), this);
		}
		else
		{
			Toast.makeText(
					this,
					"Severe! Channel is probably lost premanently. Try Disable/Re-Enable P2P.",
					Toast.LENGTH_LONG).show();
		}
	}

	@Override
	public void cancelDisconnect()
	{
		/*
		 * A cancel abort request by user. Disconnect i.e. removeGroup if
		 * already connected. Else, request WifiP2pManager to abort the ongoing
		 * request
		 */
		if (manager != null)
		{
			final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager()
					.findFragmentById(R.id.frag_list);
			if (fragment.getDevice() == null
					|| fragment.getDevice().status == WifiP2pDevice.CONNECTED)
			{
				disconnect();
			}
			else
				if (fragment.getDevice().status == WifiP2pDevice.AVAILABLE
						|| fragment.getDevice().status == WifiP2pDevice.INVITED)
				{
					manager.cancelConnect(channel, new ActionListener()
					{
						@Override
						public void onSuccess()
						{
							Toast.makeText(WiFiDirectActivity.this,
									"Aborting connection", Toast.LENGTH_SHORT)
									.show();
						}

						@Override
						public void onFailure(int reasonCode)
						{
							Toast.makeText(
									WiFiDirectActivity.this,
									"Connect abort request failed. Reason Code: "
											+ reasonCode, Toast.LENGTH_SHORT)
									.show();
						}
					});
				}
		}
	}

	@Override
	public void onClick(View v)
	{
		// TODO Auto-generated method stub
		switch (v.getId())
		{
			case R.id.atn_direct_enable:
				if (manager != null && channel != null)
				{
					// Since this is the system wireless settings activity, it's
					// not going to send us a result. We will be notified by
					// WiFiDeviceBroadcastReceiver instead.
					startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
				}
				else
				{
					Log.e(TAG, "channel or manager is null");
				}
				break;

			case R.id.atn_direct_discover:
				if (!isWifiP2pEnabled)
				{
					Toast.makeText(WiFiDirectActivity.this,
							R.string.p2p_off_warning, Toast.LENGTH_SHORT)
							.show();
					break;
				}
				final DeviceListFragment fragment = (DeviceListFragment) getFragmentManager()
						.findFragmentById(R.id.frag_list);
				fragment.onInitiateDiscovery();
				manager.discoverPeers(channel,
						new WifiP2pManager.ActionListener()
						{
							@Override
							public void onSuccess()
							{
								Toast.makeText(WiFiDirectActivity.this,
										"Discovery Initiated",
										Toast.LENGTH_SHORT).show();
							}

							@Override
							public void onFailure(int reasonCode)
							{
								Toast.makeText(WiFiDirectActivity.this,
										"Discovery Failed : " + reasonCode,
										Toast.LENGTH_SHORT).show();
							}
						});
		}

	}
}
